package com.dddframework.mq.redis;

import cn.hutool.core.util.IdUtil;
import com.dddframework.core.context.SpringContext;
import org.springframework.data.redis.connection.stream.Record;
import org.springframework.data.redis.stream.StreamListener;
import org.springframework.util.ErrorHandler;

/**
 * 消息中间件
 *
 * @author Liyj
 */
public interface IMessageListener<B, K, V extends Record<K, ?>> extends StreamListener<K, V> {

    /**
     * 接收消息后是否自动 ACK
     */
    default boolean autoAck() {
        return true;
    }

    /**
     * 分组归类
     * <p>
     * 消费组 相互独立，互相不受影响；同一份 stream 内部的消息会被每个消费组都消费到。
     */
    default String group() {
        return SpringContext.getEnv().getProperty("spring.application.name");
    }

    /**
     * 消费者名称
     * 同一个消费组可以挂接多个消费；用一个消费组内 所有的消费者都是是竞争关系，同一条消息只能被一个消费者处理
     */
    default String consumer() {
        return IdUtil.getSnowflakeNextIdStr();
    }

    /**
     * 订阅频道 redis Stream 的方式不需要写
     */
    default String topic() {
        return null;
    }


    /**
     * 消息队列名称 key
     */
    default String queue() {
        return "DEFAULT_QUEUE";
    }

    /**
     * 消息监听
     */
    void receive(B message);

    default ErrorHandler errorHandler() {
        return this::handleError;
    }

    default void handleError(Throwable throwable) {
    }

}
